﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Model;

namespace ObserverLib
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Mailing" in both code and config file together.
    public class Mailing : IMailing
    {
        private static readonly List<IMessageCallback> Burglars
                   = new List<IMessageCallback>();

        private static readonly List<Palace> Palaces = new List<Palace>();

        public static void NotifyActivity(Palace activity)
        {
            Burglars.ForEach(delegate(IMessageCallback callback){
                if (((ICommunicationObject)callback).State == CommunicationState.Opened){
                    callback.PalaceActivity(activity);
                }
                else{
                    Unsubcribe(callback);
                }
            });
        }

        //TODO: May be those method not needed?
        public static void NotifyNewPalace(Palace palace)
        {

            if (!Palaces.Contains(palace))
                Palaces.Add(palace);

            Burglars.ForEach(delegate(IMessageCallback callback){
                if (((ICommunicationObject)callback).State == CommunicationState.Opened){
                    callback.PalaceAdded(palace);
                }
                else{
                    Unsubcribe(callback);
                }
            });
        }

        public static void NotifyPalaceRemove(Palace palace)
        {
            if (Palaces.Contains(palace))
                Palaces.Remove(palace);

            Burglars.ForEach(delegate(IMessageCallback callback)
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened){
                    callback.PalaceRemoved(palace);
                }
                else{
                    Unsubcribe(callback);
                }
            });
        }

        public List<Palace> Subscribe(String name)
        {
            try
            {
                var callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
                if (!Burglars.Contains(callback))
                    lock (Burglars)
                    {
                        Burglars.Add(callback);
                    }

            }
            catch (Exception){

            }
            return Palaces;
        }

        public void Unsubscribe()
        {
            try
            {
                var callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
                if (Burglars.Contains(callback))
                    Unsubcribe(callback);
            }
            catch (Exception){

            }
        }



        public static void Alert(InvasionAlert alert)
        {
            Burglars.ForEach(delegate(IMessageCallback callback)
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened){
                    callback.PalaceBurglarAlert(alert);
                }
                else{
                    Unsubcribe(callback);
                }
            });
        }

        private static void Unsubcribe(IMessageCallback callback)
        {
            lock (Burglars)
            {
                Burglars.Remove(callback);
            }
        }
    }
}
